<?php

/**
 * Cubi Application Platform
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @package   openbiz.bin
 * @copyright Copyright (c) 2005-2011, Rocky Swen
 * @license   http://www.opensource.org/licenses/bsd-license.php
 * @link      http://www.phpopenbiz.org/
 * @version   $Id$
 */

/**
 * FormGenerator class
 *
 * Generate FormObject (DO) metafile
 *
 * @package   cubi.bin.tools
 * @author    Rocky Swen
 * @copyright Copyright (c) 2005-2010, Rocky Swen
 * @access    public
 */
class FormGenerator
{
    const LIST_TEMPLATE = "/f_TemplateList.xml";
    const DETAIL_TEMPLATE = "/f_TemplateDetail.xml";    
    const EDIT_TEMPLATE = "/f_TemplateEdit.xml";
    const NEW_TEMPLATE = "/f_TemplateNew.xml";
    const COPY_TEMPLATE = "/f_TemplateCopy.xml";
    const EDIT_ATTACHMENT_TEMPLATE = "/f_TemplateEditAttachment.xml";
    const EDIT_PICTURE_TEMPLATE = "/f_TemplateEditPicture.xml";
    
    const CHECK_LIST_TEMPLATE = "/f_TemplateCheckList.xml";        
    const CHECK_DETAIL_TEMPLATE = "/f_TemplateCheckDetail.xml";    
    
    const NEED_CHECK_LIST_TEMPLATE = "/f_TemplateNeedCheckList.xml";    
    const NEED_CHECK_DETAIL_TEMPLATE = "/f_TemplateNeedCheckDetail.xml";    
    
    const APPROVE_LIST_TEMPLATE = "/f_TemplateApproveList.xml";    
    const APPROVE_DETAIL_TEMPLATE = "/f_TemplateApproveDetail.xml";
    
    const NEED_APPROVE_LIST_TEMPLATE = "/f_TemplateNeedApproveList.xml";
    const NEED_APPROVE_DETAIL_TEMPLATE = "/f_TemplateNeedApproveDetail.xml";
    
    const READ_LIST_TEMPLATE            = "/f_TemplateReadList.xml";
    const READ_DETAIL_TEMPLATE          = "/f_TemplateReadDetail.xml";
    const READ_CHECK_LIST_TEMPLATE      = "/f_TemplateReadCheckList.xml";
    const READ_CHECK_DETAIL_TEMPLATE    = "/f_TemplateReadCheckDetail.xml";
    const READ_APPROVE_LIST_TEMPLATE    = "/f_TemplateReadApproveList.xml";
    const READ_APPROVE_DETAIL_TEMPLATE  = "/f_TemplateReadApproveDetail.xml";
    
    const DETAIL_TPL = "/f_TemplateDetail.tpl";
    const DETAIL_ES_TPL = "/f_TemplateDetailElementSet.tpl";
    const GRID_TPL = "/f_TemplateGrid.tpl";
    
    const PHP_APPROVE_FORM_TEMPLATE = "/php_ApproveForm.php";
    const PHP_GENERAL_FORM_TEMPLATE = "/php_GeneralForm.php";

    /**
     *
     * @var MetaGenerator 
     */
    public $metaGen;

    /**
     * Package name (path.path.path)
     * @var string
     */
    public $package_name;

    /**
     * view name
     * @var string
     */
    public $view_name;

    /**
     * More option parameters
     * @var array
     */
    public $options;

    
    public $form_short_name;
    
    /**
     * Form name of data list
     * @var string
     */
    public $list_form;

    /**
     * Form name of new entry form
     * @var string 
     */
    public $new_form;

    /**
     * Form name of edit entry form
     * @var <type>
     */
    public $edit_form;

    /**
     * Form name of copy entry form
     * @var string
     */
    public $copy_form;

    /**
     * Form name of detail form
     * @var string
     */
    public $detail_form;

    /**
     * Form name of edit attachment form
     * @var string
     */
    public $edit_attachment_form;

    
    public $php_general_form;
    public $php_approval_form;

    /**
     * Form name of edit picture form
     * @var string
     */
    public $edit_picture_form;

    public $check_list_form;
    public $check_detail_form;

    public $need_check_list_form;
    public $need_check_detail_form;

    public $approve_list_form;
    public $approve_detail_form;

    public $need_approve_list_form;
    public $need_approve_detail_form; 

    public $read_list_form;
    public $read_detail_form;
    public $read_check_list_form;
    public $read_check_detail_form;
    public $read_approve_list_form;
    public $read_approve_detail_form;
    
    /**
     * DOGenerator object
     * @var DOGenerator
     */
    public $doGen;

    /**
     * search columns
     * @var array
     */
    public $search_cols = array();

    /**
     * Message file name
     * @var string
     */
    public $message_file = "";

    /**
     * Event name
     * @var string
     */
    public $event_name = "";

    /**
     * Form object class name, default is EasyForm
     * @var string
     */
    public $class_general_form;

    
    public $class_approval_form;

    /**
     * ACL name
     * @var string
     */
    public $acl_name = "";

    /**
     * Initialize
     *
     * @param string $package_name module name
     * @param DOGenerator $doGen DOGenerator object
     * @param array $options
     * @return void
     */
    function __construct($package_name, $doGen, $options)
    {
        $this->package_name = $package_name;
        $this->doGen = $doGen;
        $table_name = $doGen->table_name;

        $this->options = $options;
        $this->view_name = 'view.' . $options[1] . 'View';
        $this->list_form = 'form.' . $options[1] . 'ListForm';
        $this->new_form = 'form.' . $options[1] . 'NewForm';
        $this->edit_form = 'form.' . $options[1] . 'EditForm';
        $this->copy_form = 'form.' . $options[1] . 'CopyForm';
        $this->detail_form = 'form.' . $options[1] . 'DetailForm';     

        $this->edit_attachment_form = 'form.' . $options[1] . 'EditAttachmentForm';
        $this->edit_picture_form = 'form.' . $options[1] . 'EditPictureForm';

        $this->check_list_form = 'form.' . $options[1] . 'CheckListForm';
        $this->check_detail_form = 'form.' . $options[1] . 'CheckDetailForm';
        
        $this->need_check_list_form = 'form.' . $options[1] . 'NeedCheckListForm';
        $this->need_check_detail_form = 'form.' . $options[1] . 'NeedCheckDetailForm';
        
        $this->approve_list_form = 'form.' . $options[1] . 'ApproveListForm';
        $this->approve_detail_form = 'form.' . $options[1] . 'ApproveDetailForm';
        
        $this->need_approve_list_form = 'form.' . $options[1] . 'NeedApproveListForm';
        $this->need_approve_detail_form = 'form.' . $options[1] . 'NeedApproveDetailForm';
        
        $this->php_general_form = $options[1] . 'Form';
        $this->php_approval_form = $options[1] . 'ApproveForm';        
        
        $this->read_list_form = 'form.' . $options[1] . 'ReadListForm';
        $this->read_detail_form = 'form.' . $options[1] . 'ReadDetailForm';     
        
        $this->read_check_list_form = 'form.' . $options[1] . 'ReadCheckListForm';
        $this->read_check_detail_form = 'form.' . $options[1] . 'ReadCheckDetailForm';
        
        $this->read_approve_list_form = 'form.' . $options[1] . 'ReadApproveListForm';
        $this->read_approve_detail_form = 'form.' . $options[1] . 'ReadApproveDetailForm';
  
        $this->class_general_form = $this->php_general_form;
        $this->class_approval_form = $this->php_approval_form;
        
        foreach ($doGen->tableIndex as $index) {
            foreach ($index as $search) {
                array_push($this->search_cols, $search);
            }
        }        
    }

    /**
     * Generate all form metafiles
     *
     * @return array list of form file name
     */
    public function generateAllForms()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';

        // copy templates file grid.tpl and detail.tpl
        GenitHelper::copyTemplateFile("detail.tpl", $templateDirectory . META_TPL . self::DETAIL_TPL, $this->package_name);
        GenitHelper::copyTemplateFile("detail_elementset.tpl", $templateDirectory . META_TPL . self::DETAIL_ES_TPL, $this->package_name);
        GenitHelper::copyTemplateFile("grid.tpl", $templateDirectory . META_TPL . self::GRID_TPL, $this->package_name);

        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_default;
        $formFiles[] = $this->generateForm($this->read_list_form, $templateDirectory . META_TPL . self::READ_LIST_TEMPLATE);
        $formFiles[] = $this->generateForm($this->read_detail_form, $templateDirectory . META_TPL . self::READ_DETAIL_TEMPLATE);
        
        if ($this->doGen->hasCheckProcess()) {
            $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_need_check;
        }
        
        $formFiles[] = $this->generateForm($this->list_form, $templateDirectory . META_TPL . self::LIST_TEMPLATE);
        $formFiles[] = $this->generateForm($this->new_form, $templateDirectory . META_TPL . self::NEW_TEMPLATE);
        $formFiles[] = $this->generateForm($this->edit_form, $templateDirectory . META_TPL . self::EDIT_TEMPLATE);
        $formFiles[] = $this->generateForm($this->detail_form, $templateDirectory . META_TPL . self::DETAIL_TEMPLATE);
        $formFiles[] = $this->generateForm($this->copy_form, $templateDirectory . META_TPL . self::COPY_TEMPLATE);
        
        
        $formFiles[] = $this->generateForm($this->php_general_form, $templateDirectory . META_TPL . self::PHP_GENERAL_FORM_TEMPLATE);

        if ($this->doGen->hasExternalAttachment()) {
            $formFiles[] = $this->generateForm($this->edit_attachment_form, $templateDirectory . META_TPL . self::EDIT_ATTACHMENT_TEMPLATE);
        }

        if ($this->doGen->hasExternalPicture()) {
            $formFiles[] = $this->generateForm($this->edit_picture_form, $templateDirectory . META_TPL . self::EDIT_PICTURE_TEMPLATE);
        }

        if ($this->doGen->hasCheckProcess()) {
            $formFiles[] = $this->_generateNeedCheckListForm();
            $formFiles[] = $this->_generateNeedCheckDetailForm();
            $formFiles[] = $this->_generateCheckedListForm();
            
            $formFiles[] = $this->_generateReadCheckedListForm();
            
            $formFiles[] = $this->_generateCheckedDetailForm();
            
            $formFiles[] = $this->_generateReadCheckedDetailForm();            
        }

        if ($this->doGen->hasApproveProcess()) {
            $formFiles[] = $this->_generateNeedApproveListForm();
            $formFiles[] = $this->_generateNeedApproveDetailForm();
            $formFiles[] = $this->_generateApprovedListForm();
            
            $formFiles[] = $this->_generateReadApprovedListForm();
            
            $formFiles[] = $this->_generateApprovedDetailForm();
            
            $formFiles[] = $this->_generateReadApprovedDetailForm();
        }

        //echo "\n\n\n" . $this->php_approval_form . "  | " .  $templateDirectory . META_TPL . self::PHP_APPROVE_FORM_TEMPLATE;
            
        $formFiles[] = $this->generateForm($this->php_approval_form, $templateDirectory . META_TPL . self::PHP_APPROVE_FORM_TEMPLATE);
        
        return $formFiles;
    }

    private function _generateCheckedListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_checked;
        return $this->generateForm($this->check_list_form, $templateDirectory . META_TPL . self::CHECK_LIST_TEMPLATE);
    }

    private function _generateReadCheckedListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_checked;
        return $this->generateForm($this->read_check_list_form, $templateDirectory . META_TPL . self::READ_CHECK_LIST_TEMPLATE);
    }
    
    private function _generateCheckedDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_checked;
        return $this->generateForm($this->check_detail_form, $templateDirectory . META_TPL . self::CHECK_DETAIL_TEMPLATE);
    }
    
    private function _generateReadCheckedDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_checked;
        return $this->generateForm($this->read_check_detail_form, $templateDirectory . META_TPL . self::READ_CHECK_DETAIL_TEMPLATE);
    }
    
    private function _generateNeedCheckListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_need_check;
        return $this->generateForm($this->need_check_list_form, $templateDirectory . META_TPL . self::NEED_CHECK_LIST_TEMPLATE);
    }

    private function _generateNeedCheckDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_need_check;
        return $this->generateForm($this->need_check_detail_form, $templateDirectory . META_TPL . self::NEED_CHECK_DETAIL_TEMPLATE);
    }
    
    
    private function _generateApprovedListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_approved;
        return $this->generateForm($this->approve_list_form, $templateDirectory . META_TPL . self::APPROVE_LIST_TEMPLATE);
    }
    
    private function _generateReadApprovedListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_approved;
        return $this->generateForm($this->read_approve_list_form, $templateDirectory . META_TPL . self::READ_APPROVE_LIST_TEMPLATE);
    }

    private function _generateApprovedDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_approved;
        return $this->generateForm($this->approve_detail_form, $templateDirectory . META_TPL . self::APPROVE_DETAIL_TEMPLATE);
    }
    
    private function _generateReadApprovedDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_approved;
        return $this->generateForm($this->read_approve_detail_form, $templateDirectory . META_TPL . self::READ_APPROVE_DETAIL_TEMPLATE);
    }    
    
    private function _generateNeedApproveListForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_need_approve;
        return $this->generateForm($this->need_approve_list_form, $templateDirectory . META_TPL . self::NEED_APPROVE_LIST_TEMPLATE);
    }

    private function _generateNeedApproveDetailForm()
    {
        $templateDirectory = dirname(dirname(__FILE__)) . '/templates/';
        $this->doGen->do_name = 'do.' . $this->doGen->do_short_name_need_approve;
        return $this->generateForm($this->need_approve_detail_form, $templateDirectory . META_TPL . self::NEED_APPROVE_DETAIL_TEMPLATE);
    }
    
    /**
     * Generate form metafile
     *
     * @param string $form_name form name
     * @param string $templateFile name of template file
     * @return string
     */
    public function generateForm($form_name, $templateFile)
    {

        $do_short_name = $this->doGen->do_short_name;

         $this->form_short_name = str_replace("form.", "", $form_name);

        if (CLI) {
            echo "Start generate form object $this->form_short_name." . PHP_EOL;
        }
        $targetPath = $moduleDir = MODULE_PATH . "/" . str_replace(".", "/", $this->package_name) . "/form";
        if (!file_exists($targetPath)) {
            if (CLI) {
                echo "Create directory $targetPath" . PHP_EOL;
            }
            mkdir($targetPath, 0777, true);
        }

        $content = $this->_assignToSmarty($templateFile);
        
        // target file
        $targetFile = $targetPath . "/" . $this->form_short_name . "." . $this->_getExtension($templateFile);
        //$this->_getExtension( $templateFile );
        file_put_contents($targetFile, GenitHelper::trimEmptyLines($content));
        if (CLI) {
            echo "\t" . str_replace(MODULE_PATH, "", $targetFile) . " is generated." . PHP_EOL . PHP_EOL;
        }
        return $targetFile;
    }

    private function _assignToSmarty($templateFile)
    {
        $smarty = BizSystem::getSmartyTemplate();

        $package_path = $this->options[0];
        $base_object_name = $this->options[1];
        $module_name = $this->options[2];
        $package = $this->options[3];
        
        $smarty->assign_by_ref("package_name", $this->package_name);
        $smarty->assign_by_ref("comp", $this->package_name);
        
        $smarty->assign_by_ref("do_name", $this->doGen->do_name);
        $smarty->assign_by_ref("do_short_name", $this->doGen->do_short_name);
        //GenitDebug::ShowMessage(__CLASS__ .'::'.__METHOD__);
        //print_r($this->metaGen);
        $smarty->assign_by_ref("comp_name", $this->metaGen->compName);
        $smarty->assign_by_ref("comp_desc", $this->metaGen->compDesc);
        
        $smarty->assign_by_ref("table_name", $this->doGen->table_name);
        $smarty->assign_by_ref("fields", $this->doGen->fields);
        $smarty->assign_by_ref("view_name", $this->view_name);
        $smarty->assign_by_ref("form_name", $form_name);
        $smarty->assign_by_ref("form_short_name", $this->form_short_name);

        // form variable
        $smarty->assign_by_ref("list_form", $this->list_form);
        $smarty->assign_by_ref("new_form", $this->new_form);
        $smarty->assign_by_ref("copy_form", $this->copy_form);
        $smarty->assign_by_ref("edit_form", $this->edit_form);
        $smarty->assign_by_ref("detail_form", $this->detail_form);

        $smarty->assign_by_ref("php_general_form", $this->php_general_form);
        
        $smarty->assign_by_ref("need_check_list_form", $this->need_check_list_form);
        $smarty->assign_by_ref("need_check_detail_form", $this->need_check_detail_form);
        
        $smarty->assign_by_ref("check_list_form", $this->check_list_form);
        $smarty->assign_by_ref("check_detail_form", $this->check_detail_form);

        $smarty->assign_by_ref("need_approve_list_form", $this->need_approve_list_form);
        $smarty->assign_by_ref("need_approve_detail_form", $this->need_approve_detail_form);
        
        $smarty->assign_by_ref("approve_list_form", $this->approve_list_form);
        $smarty->assign_by_ref("approve_detail_form", $this->approve_detail_form);

        $smarty->assign_by_ref("read_list_form", $this->read_list_form);
        $smarty->assign_by_ref("read_detail_form", $this->read_detail_form);
        $smarty->assign_by_ref("read_check_list_form", $this->read_check_list_form);
        $smarty->assign_by_ref("read_check_detail_form", $this->read_check_detail_form);
        $smarty->assign_by_ref("read_approve_list_form", $this->read_approve_list_form);
        $smarty->assign_by_ref("read_approve_detail_form", $this->read_approve_detail_form);

        
        $smarty->assign_by_ref("php_approval_form", $this->php_approval_form);
        
        
        $smarty->assign_by_ref("searchs", $this->search_cols);
        $smarty->assign_by_ref("acl_name", $this->acl_name);
        $smarty->assign_by_ref("event_name", $this->event_name);
        $smarty->assign_by_ref("message_file", $this->message_file);
        
        $smarty->assign_by_ref("class_general_form", $this->class_general_form);
        $smarty->assign_by_ref("class_approval_form", $this->class_approval_form);
        
        $smarty->assign_by_ref("id_identity", $this->doGen->id_identity);

        $smarty->assign_by_ref("package", $package);
        $smarty->assign_by_ref("package_path", $package_path);
        $smarty->assign_by_ref("module_name", $module_name);
        $smarty->assign_by_ref("base_object_name", $base_object_name);

        $smarty->assign_by_ref("acl", $this->options['acl']);

        $doGen = $this->doGen;

        $smarty->assign_by_ref("has_external_attachment", $doGen->hasExternalAttachment());
        $smarty->assign_by_ref("has_external_picture", $doGen->hasExternalPicture());
        $smarty->assign_by_ref("has_external_changelog", $doGen->hasExternalChangelog() );
        $smarty->assign_by_ref("has_check_process", $doGen->hasCheckProcess());
        $smarty->assign_by_ref("has_approve_process", $doGen->hasApproveProcess());

        
        $listview_uri = strtolower(str_replace(" ", "_", $this->options[2])) . "_list";
        $listview_check_uri = strtolower(str_replace(" ", "_", $this->options[2])) . "_check_list";
        $listview_approve_uri = strtolower(str_replace(" ", "_", $this->options[2])) . "_approve_list";

        //echo "\n\n listview_check_uri : " . $listview_check_uri ."\n\n";
        $smarty->assign_by_ref("listview_uri", $listview_uri);
        $smarty->assign_by_ref("listview_check_uri", $listview_check_uri);
        $smarty->assign_by_ref("listview_approve_uri", $listview_approve_uri);
        
        
        return $smarty->fetch($templateFile);
        
    }
    
            
    private function _getExtension($fileName) {
        $ext = substr($fileName, -3);
       // echo "_getExtension : " . $ext . "\n";
        return $ext;
    }

}
